package cn.csc.module.shoppingCard.service.transaction;

import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.common.util.collection.CollectionUtils;
import cn.csc.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.csc.module.order.api.order.OrderApi;
import cn.csc.module.shoppingCard.controller.admin.transaction.vo.*;
import cn.csc.module.shoppingCard.convert.transaction.CardTransactionConvert;
import cn.csc.module.shoppingCard.dal.dataobject.card.CardDO;
import cn.csc.module.shoppingCard.dal.dataobject.transaction.CardTransactionDO;
import cn.csc.module.shoppingCard.dal.mysql.card.CardMapper;
import cn.csc.module.shoppingCard.dal.mysql.transaction.CardTransactionMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.math.BigInteger;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.csc.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csc.module.shoppingCard.enums.ErrorCodeConstants.CARD_TRANSACTION_NOT_EXISTS;

/**
 * 交易记录 Service 实现类
 *
 * @author liuchuang
 */
@Service
@Validated
@Slf4j
public class CardTransactionServiceImpl extends ServiceImpl<CardTransactionMapper, CardTransactionDO> implements CardTransactionService {

    @Autowired
    private OrderApi orderApi;

    @Autowired
    private CardMapper cardMapper;


    @Override
    public BigInteger createCardTransaction(CardTransactionCreateReqVO createReqVO) {
        // 插入
        CardTransactionDO cardTransaction = CardTransactionConvert.INSTANCE.convert(createReqVO);
        baseMapper.insert(cardTransaction);
        // 返回
        return cardTransaction.getId();
    }

    @Override
    public void updateCardTransaction(CardTransactionUpdateReqVO updateReqVO) {
        // 校验存在
        validateCardTransactionExists(updateReqVO.getId());
        // 更新
        CardTransactionDO updateObj = CardTransactionConvert.INSTANCE.convert(updateReqVO);
        baseMapper.updateById(updateObj);
    }

    @Transactional
    @Override
    public void updateStatus(List<BigInteger> orderIds){
        log.info("updateStatus 参数: {}", orderIds);
        List<CardTransactionDO> transactionDOS = baseMapper.selectByOrderIds(orderIds);
        log.info("updateStatus 交易记录: {}", transactionDOS);
        List<BigInteger> cardIds = transactionDOS.stream().map(CardTransactionDO::getCardId).collect(Collectors.toList());
        // 更新交易记录状态和交易时间
        baseMapper.updateStatus(cardIds, orderIds, (byte)1);
        List<CardDO> cardDOS = cardMapper.selectBatchIds(cardIds);
        Map<BigInteger, CardDO> doMap = CollectionUtils.convertMap(cardDOS, CardDO::getId);
        log.info("updateStatus 购物卡更新前: {}", cardDOS);
        transactionDOS.forEach(c -> {
            // 交易类型（1-充值，2-消费，3-退款，4-冻结，5-解冻）
            // TODO 目前处理 2-消费
            if (c.getTxnType() == 2){
                CardDO cardDO = doMap.get(c.getCardId());
                cardDO.setBalance(cardDO.getBalance().add(c.getAmount()));
            }
        });
        log.info("updateStatus 购物卡更新后: {}", cardDOS);
        cardMapper.updateBatch(cardDOS,1000);
    }

    @Override
    public void deleteCardTransaction(BigInteger id) {
        // 校验存在
        validateCardTransactionExists(id);
        // 删除
        baseMapper.deleteById(id);
    }

    private void validateCardTransactionExists(BigInteger id) {
        if (baseMapper.selectById(id) == null) {
            throw exception(CARD_TRANSACTION_NOT_EXISTS);
        }
    }

    @Override
    public CardTransactionDO getCardTransaction(BigInteger id) {
        return baseMapper.selectById(id);
    }

    @Override
    public List<CardTransactionDO> getByCardId(BigInteger cardId){
        return baseMapper.selectByCardId(cardId);
    }

    @Override
    public List<CardTransactionDO> getCardTransactionList(Collection<BigInteger> ids) {
        return baseMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<CardTransactionDO> getCardTransactionPage(CardTransactionPageReqVO pageReqVO) {
        return baseMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CardTransactionDO> getCardTransactionList(CardTransactionExportReqVO exportReqVO) {
        return baseMapper.selectList(exportReqVO);
    }

    @Override
    public List<CardTransactionDO> getCardTransactList(List<BigInteger> orderIds) {
        return baseMapper.selectList(new LambdaQueryWrapperX<CardTransactionDO>()
                .in(CardTransactionDO::getRelatedOrder, orderIds));
    }

    @Override
    public List<CardTransactionGroupByCardIdsRespVO> groupByCardIds(List<BigInteger> cardIds, Integer txnType, Integer status){
        return baseMapper.groupByCardIds(cardIds, txnType, status);
    }

}
